package cn.iocoder.yudao.module.product.service.skuofferpricerelation;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.enums.CurrentMarkStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
import cn.iocoder.yudao.module.product.controller.admin.skuofferpricerelation.vo.SkuOfferPriceRelationPageReqVO;
import cn.iocoder.yudao.module.product.controller.admin.skuofferpricerelation.vo.SkuOfferPriceRelationRespVO;
import cn.iocoder.yudao.module.product.controller.admin.skuofferpricerelation.vo.SkuOfferPriceRelationSaveReqVO;
import cn.iocoder.yudao.module.product.convert.skuofferpricerelation.SkuOfferPriceRelationConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
import cn.iocoder.yudao.module.product.dal.dataobject.skuofferpricerelation.SkuOfferPriceRelationDO;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
import cn.iocoder.yudao.module.product.dal.mysql.skuofferpricerelation.SkuOfferPriceRelationMapper;
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_OFFER_PRICE_RELATION_NOT_EXISTS;

/**
 * sku与报价关系 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
@Slf4j
public class SkuOfferPriceRelationServiceImpl implements SkuOfferPriceRelationService {

    @Resource
    private SkuOfferPriceRelationMapper skuOfferPriceRelationMapper;

    @Resource
    @Lazy // 循环依赖，避免报错
    private ProductSkuService productSkuService;

    @Resource
    private ProductSpuService productSpuService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createSkuOfferPriceRelation(SkuOfferPriceRelationSaveReqVO createReqVO) {
        SkuOfferPriceRelationDO skuOfferPriceRelation = SkuOfferPriceRelationConvert.INSTANCE.convertDO(createReqVO);
        //判断是否立即生效数据（是，更新当前生效的状态为往期）
        checkEffectiveSkuOfferPrice(skuOfferPriceRelation);

        skuOfferPriceRelationMapper.insert(skuOfferPriceRelation);

        return skuOfferPriceRelation.getId();
    }

    /**
     * 立即生效定价
     * @param: skuOfferPriceRelation
     * @return: void
     * @author xulimin
     * @date: 2023/12/28 9:30
     */
    private void checkEffectiveSkuOfferPrice(SkuOfferPriceRelationDO skuOfferPriceRelation) {
        if(null != skuOfferPriceRelation.getEffective() && skuOfferPriceRelation.getEffective() == Boolean.TRUE){
            //获取当前使用定价
            SkuOfferPriceRelationDO skuOfferPriceRelationDO = getSkuOfferPriceRelationBySkuId(skuOfferPriceRelation.getSkuId());
            skuOfferPriceRelationDO.setCurrentMark(CurrentMarkStatusEnum.GO_OVER.getStatus());
            //跟新数据
           skuOfferPriceRelationMapper.updateById(skuOfferPriceRelationDO);
            //更新商品价格
            productSkuService.updateSkuById(skuOfferPriceRelation.getSkuId(),skuOfferPriceRelation.getPrice());

            skuOfferPriceRelation.setCurrentMark(CurrentMarkStatusEnum.CURR.getStatus());
        }else {
            skuOfferPriceRelation.setCurrentMark(CurrentMarkStatusEnum.NEXT.getStatus());
        }
    }


    @Override
    public void updateSkuOfferPriceRelation(SkuOfferPriceRelationSaveReqVO updateReqVO) {
        // 校验存在
        validateSkuOfferPriceRelationExists(updateReqVO.getId());
        // 更新
        SkuOfferPriceRelationDO updateObj = SkuOfferPriceRelationConvert.INSTANCE.convertDO(updateReqVO);
        //判断是否立即生效数据（是，更新当前生效的状态为往期）
        checkEffectiveSkuOfferPrice(updateObj);

        skuOfferPriceRelationMapper.updateById(updateObj);
    }

    @Override
    public void deleteSkuOfferPriceRelation(Long id) {
        // 校验存在
        validateSkuOfferPriceRelationExists(id);
        // 删除
        skuOfferPriceRelationMapper.deleteById(id);
    }

    private void validateSkuOfferPriceRelationExists(Long id) {
        if (skuOfferPriceRelationMapper.selectById(id) == null) {
            throw exception(SKU_OFFER_PRICE_RELATION_NOT_EXISTS);
        }
    }

    @Override
    public SkuOfferPriceRelationDO getSkuOfferPriceRelation(Long id) {
        return skuOfferPriceRelationMapper.selectById(id);
    }

    @Override
    public PageResult<SkuOfferPriceRelationDO> getSkuOfferPriceRelationPage(SkuOfferPriceRelationPageReqVO pageReqVO) {
        return skuOfferPriceRelationMapper.selectPage(pageReqVO);
    }

    @Override
    public SkuOfferPriceRelationDO getSkuOfferPriceRelationBySkuId(Long skuId) {
        LambdaQueryWrapper<SkuOfferPriceRelationDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SkuOfferPriceRelationDO::getSkuId,skuId);
        lambdaQueryWrapper.eq(SkuOfferPriceRelationDO::getCurrentMark, CurrentMarkStatusEnum.CURR.getStatus());
        return skuOfferPriceRelationMapper.selectOne(lambdaQueryWrapper);
    }

    @Override
    public void updateSkuOfferPriceRelationByIds(List<Long> skuIdList) {
        LambdaUpdateWrapper<SkuOfferPriceRelationDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.in(SkuOfferPriceRelationDO::getSkuId,skuIdList);
        lambdaUpdateWrapper.set(SkuOfferPriceRelationDO::getCurrentMark,CurrentMarkStatusEnum.GO_OVER.getStatus());
        skuOfferPriceRelationMapper.update(lambdaUpdateWrapper);
    }

    @Override
    public void updateSkuOfferPriceRelationById(SkuOfferPriceRelationDO skuOfferPriceRelationDO) {
        skuOfferPriceRelationMapper.updateById(skuOfferPriceRelationDO);
    }

    @Override
    public List<SkuOfferPriceRelationRespVO> getSkuOfferPriceRelationListBySkuId(Long skuId) {
        QueryWrapperX<SkuOfferPriceRelationDO> queryWrapperX = new QueryWrapperX<>();
        queryWrapperX.eqIfPresent("sku_id",skuId);
        queryWrapperX.neIfPresent("current_mark",CurrentMarkStatusEnum.GO_OVER.getStatus());
        List<SkuOfferPriceRelationRespVO> skuOfferPriceRelationRespVOS = SkuOfferPriceRelationConvert.INSTANCE.convertVOList(skuOfferPriceRelationMapper.selectList(queryWrapperX));
        if(CollUtil.isNotEmpty(skuOfferPriceRelationRespVOS)){
            skuOfferPriceRelationRespVOS.forEach(skuOfferPriceRelationRespVO -> {
                //设置属性
                ProductSkuDO productSkuDO = productSkuService.getSku(skuOfferPriceRelationRespVO.getSkuId());
                if(ObjectUtils.isNotEmpty(productSkuDO)){
                    skuOfferPriceRelationRespVO.setProperties(productSkuDO.getProperties());
                    //设置名称
                    ProductSpuDO productSpuDO = productSpuService.getSpu(productSkuDO.getSpuId());
                    skuOfferPriceRelationRespVO.setName(productSpuDO.getName());
                }

            });
        }
        return skuOfferPriceRelationRespVOS;
    }

    @Override
    public void createSkuOfferPrice(SkuOfferPriceRelationSaveReqVO skuOfferPriceRelationSaveReqVO) {
        skuOfferPriceRelationMapper.insert(SkuOfferPriceRelationConvert.INSTANCE.convertDO(skuOfferPriceRelationSaveReqVO));
    }

    @Override
    public int handleEffectiveOfferPrice() {
        int count  = 0;
        QueryWrapperX<SkuOfferPriceRelationDO> queryWrapperX = new QueryWrapperX<>();
        queryWrapperX.ne("current_mark",2);
        List<SkuOfferPriceRelationDO> skuOfferPriceRelationDOList = skuOfferPriceRelationMapper.selectList(queryWrapperX);
        log.info("skuOfferPriceRelationMapper.selectList siz:{}",skuOfferPriceRelationDOList.size());
        if(CollUtil.isEmpty(skuOfferPriceRelationDOList)){
          return count;
        }

        //根据skuId分组
        Map<Long, List<SkuOfferPriceRelationDO>> maps = skuOfferPriceRelationDOList.stream().collect(Collectors.groupingBy(SkuOfferPriceRelationDO::getSkuId));
        for (Map.Entry<Long, List<SkuOfferPriceRelationDO>> entry : maps.entrySet()) {
            List<SkuOfferPriceRelationDO> skuOfferPriceRelationDOS = entry.getValue();
            //当前时间内定价
            List<SkuOfferPriceRelationDO> currTimeOfferPrice = Lists.newArrayList();
            //当前使用的定价
            List<SkuOfferPriceRelationDO> usrCurrOfferPrice = Lists.newArrayList();
            skuOfferPriceRelationDOS.forEach(skuOfferPriceRelationDO -> {
                if(null !=skuOfferPriceRelationDO.getEffectiveTime() && LocalDateTime.now().isAfter(skuOfferPriceRelationDO.getEffectiveTime())
                        && CurrentMarkStatusEnum.NEXT.getStatus().equals(skuOfferPriceRelationDO.getCurrentMark())){
                    currTimeOfferPrice.add(skuOfferPriceRelationDO);
                }
                if(CurrentMarkStatusEnum.CURR.getStatus().equals(skuOfferPriceRelationDO.getCurrentMark())){
                    usrCurrOfferPrice.add(skuOfferPriceRelationDO);
                }
            });

            if(CollUtil.isEmpty(currTimeOfferPrice)){
                log.info("handleEffectiveOfferPrice 未处理的数据:{}",entry.getKey());
                continue;
            }
            //更新数据
            updateOfferPriceRelation(currTimeOfferPrice,usrCurrOfferPrice);
            count++;
        }
        return count;
    }


    /**
     * 更新数据
     * @param: currTimeOfferPrice
     * @param: usrCurrOfferPrice
     * @return: void
     * @author xulimin
     * @date: 2023/12/27 17:48
     */
    private void updateOfferPriceRelation(List<SkuOfferPriceRelationDO> currTimeOfferPrice, List<SkuOfferPriceRelationDO> usrCurrOfferPrice) {
        List<SkuOfferPriceRelationDO> list = Lists.newArrayList();
        if(CollUtil.isNotEmpty(currTimeOfferPrice)){
            currTimeOfferPrice.forEach(skuOfferPriceRelationDO -> {
                skuOfferPriceRelationDO.setCurrentMark(CurrentMarkStatusEnum.CURR.getStatus());
                list.add(skuOfferPriceRelationDO);
                productSkuService.updateSkuById(skuOfferPriceRelationDO.getSkuId(),skuOfferPriceRelationDO.getPrice());
            });
        }

        if(CollUtil.isNotEmpty(usrCurrOfferPrice)){
            usrCurrOfferPrice.forEach(skuOfferPriceRelationDO -> {
                skuOfferPriceRelationDO.setCurrentMark(CurrentMarkStatusEnum.GO_OVER.getStatus());
                list.add(skuOfferPriceRelationDO);
            });
        }

        log.info("updateOfferPriceRelation 需要跟新是数据list:{}",list);
        skuOfferPriceRelationMapper.updateBatch(list,list.size());
    }
}